package com.jzhao.jpre.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

public class SystemHelper extends ClassLoader {
	public SystemHelper(ClassLoader parent) {
		super(parent);
	}
	
	public URL getResource(String name) {
		return getParent().getResource(name);
	}
	
	protected Class findClass(String className) throws ClassNotFoundException {
		//System.out.println("loading class: " + className);
		if (className.endsWith("BeanInfo")) {
			throw new ClassNotFoundException();
		}
		Class cls = findLoadedClass(className);
		if (null == cls) {
			cls = loadAllClasses(className);
			if (null == cls) {
				throw new ClassNotFoundException(className);
			}
			//System.out.println(className + " loaded!");
		}else {
			//System.out.println(className + " has loaded by " + cls.getClassLoader());
		}
		return cls;
	}
	
	private File[] getClassFile(String className) {
		StringBuffer base = new StringBuffer(getParent().getResource("/").getPath());
		int lastdot = className.lastIndexOf('.');
		
		String fullname = className.replace('.', File.separatorChar);
		
		base.append(fullname.substring(0, lastdot));
		base.append(File.separatorChar);
		base.append("sec");
		base.append(File.separatorChar);	
		String filepath = base.toString();
		
		String filename = fullname.substring(lastdot + 1);
		
		File dir = new File(filepath);
		
		return dir.listFiles(new ClassFileFilter(filename));
	}
	
	private Class loadAllClasses(String className) throws ClassNotFoundException {
		try {
			Class ret = null;
			File[] files = getClassFile(className);
			for (int i = 0; i < files.length; i++) {
				FileInputStream fis = new FileInputStream(files[i]);
				byte[] contents = new byte[fis.available()];
				fis.read(contents);
				byte[] classBytes = decrypt(contents);
				Class cls = defineClass(className, classBytes, 0, classBytes.length);
				if (i == 0) {
					ret = cls;
				}
			}
			return ret;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new ClassNotFoundException(className);
		} catch (IOException e) {
			e.printStackTrace();
			throw new ClassNotFoundException(className);
		}
	}
	private byte[] decrypt(byte[] source) {
		return source;
	}
	public String toString() {
		return "Custom classloader";
	}
}

class ClassFileFilter implements FilenameFilter {

	ClassFileFilter(String pattern) {
		this.pattern = pattern;
	}
	
	public boolean accept(File dir, String name) {
		return name.equals(pattern) || name.startsWith(pattern + "$");
	}
	private String pattern;
}